/**
 * @author Hemant
 * This is a public class.It generates a text file with html tag objects and 
 * its properties from tag objects registered in Master.     
 * Its one of the important classes in POOL web 
 * package . It accepts an object, find its properties 
 * and generate  a text file contaning object and its properties in a specific format.
 */

/*
*Released on 28th June 2008.
*Any violations can be reported at paritosh@wikiocean.net
*What is treated as violations can be found at www.wikiocean.net/ppl1-voilations*
******************************************************************************
* The contents of this file are subject to POOL Public License 1.0 and later.
* POOL Public License is based on Affero GPL v3 and additional conditions.
* ("License"); You may not use this file except in compliance with the License
* You may obtain a copy of the Affero GPL v3 License at http://www.gnu.org/licenses/agpl.html
* You may obtain a copy of the POOL Public License 1.0 or later at www.wikiocean.net/license/ppl.html
* Software distributed under POOL Public License 1.0 is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
* The Initial Developer of the Original Code is Paritosh Pungaliya (C) 2008. All Rights Reserved.
******************************************************************************
* Objective of the additional terms (license)
* 1) Is to extend the software freedom to freedom to work.
* 2) To ensure that knowledge is free from monopoly of agencies.
* 3) To avoid a situation where big corporate or investor can buy out free software groups and companies and then start milking the communities built around it.
* (this trend can be seen how the freedom is curtailed in companies that get Venture Capital funding.)
******************************************************************************
*/

package  guifilegenerator;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.sql.ResultSet;
import java.util.Hashtable;
import java.util.Vector;


import utility.Input;
import utility.Replace;
import file.FileUtility;
import file.SearchRecord;
import database.RecordSearch;
import dbmanager.*;
import sort.*;

public class GenerateTextFile
{
    private GetIdName get;
    RandomAccessFile rafNew;
    static boolean flag = false;
    String level = "",path,ReportId;
    int counter = 0,midIndex,pidIndex,pvIndex,vtIndex,refIndex;
    String fileformat;
    
    Vector<Object> objects ;
    
    /**
     * Conctructor accepts tag object name and path for new file to be generated.
     * @param ReportId It is the mastername of registered report.
     * @param db DBManager object
     */
    public GenerateTextFile(String ReportId, String fileformat) 
    {
    	try
    	{
    		//Create GetIdName object
	        get = new GetIdName();
	        
	        this.fileformat = fileformat;
	        //Get master id for Report
	        this.ReportId = ReportId;
	        System.out.println("ReportId :"+ReportId);     
	        path = Input.WEB_REPORTS_FILES+get.getItem(ReportId)+Input.FILRFORMAT;
	        //this.generateFile(ReportNameId);	     	
	        
	     // Get coloumn indices
	        midIndex = Column.mid_index-1;
	        pidIndex = Column.pid_index-1;
	        pvIndex = Column.pv_index-1;
	        vtIndex = Column.vt_index-1;
	        refIndex = Column.ref_index-1;
	        
	        objects = new Vector<Object>();
	        objects.add("tag");
	        objects.add("attribute");
	        objects.add("displaytext");
	        objects.add("vertical");
	        objects.add("fieldlist");
	        objects.add("field");
	        objects.add("headinglist");
	        objects.add("heading");
	        objects.add("select");
	        objects.add("noselect");	        
    	}
    	catch (Exception e) 
    	{
                e.printStackTrace();
        }          
    }

    public GenerateTextFile(RandomAccessFile raf, String level, int counter) 
    {
    	this.rafNew = raf;
    	this.level = level;
    	this.counter = counter;
    	get = new GetIdName();
    	// Get coloumn indices
        midIndex = Column.mid_index-1;
        pidIndex = Column.pid_index-1;
        pvIndex = Column.pv_index-1;
        vtIndex = Column.vt_index-1;
        refIndex = Column.ref_index-1;
        
        objects = new Vector<Object>();
        objects.add("tag");
        objects.add("attribute");
        objects.add("displaytext");
        objects.add("vertical");
        objects.add("fieldlist");
        objects.add("field");
        objects.add("headinglist");
        objects.add("heading");
        objects.add("select");
        objects.add("noselect");
        objects.add("css");
	}
    
    public void setDatabase()
    {    	
  	  //Create GetIdName object
	     get = new GetIdName();
    }
    
    public void setFileFormat(String fileformat)
    {
    	this.fileformat = fileformat;
    }

    /**
     * This method accepts master id for the tag object i.e. ReportName 
     * and writes Text file with tag objects and its properties.
     * @return Returns true if file created.
     */
    public boolean generateFile()
    {
    	boolean filecreated = false;
    	//System.out.println("I'm in generateFile() ");
    	//System.out.println("The path is "+path);
        File newfile = new File(path);
        
        if(!newfile.exists())
        {
        	try 
        	{
				if(newfile.createNewFile())
					filecreated = true;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        }
        else
        {
        	System.out.println("File alreday exists");
        	newfile.delete();
        	
        	if(!newfile.exists())
	        {
	        	try {
					if(newfile.createNewFile())
						filecreated = true;
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
	        }
        	else
        	{
        		System.out.println("File cannot be deleted");
        	}
        }
        
        // Create random access file object for ReportName path
        try {
			rafNew = new RandomAccessFile(newfile,"rw");
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
    	
    	try
    	{
            String[] records = this.serachForChildProperty(ReportId);
            
            if(records.length!= 0)
            {
                 writeToFile(ReportId,records);      
                 rafNew.close();
            }
            else
            {
                System.out.println("The master has no properties");
            }        	           
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        
        return filecreated;
    }
    
    /**
     * This method searches for a child property for specifies master id
     * using reports.
     * @param mid Its the master id for which properties are to be searched.
     * @return It returns a String array containg proprties of mid.
     */
   public String [] serachForChildProperty(String mid)
   {
    	Hashtable<Object, Object> condition = new Hashtable<Object, Object>();
    	ArraySort sort = new ArraySort();
    	
    	try
    	{
			condition.put("mid", mid);
			condition.put("td", "null");
			RecordSearch rs = new RecordSearch();
			rs.setConditionMap(condition);
			return sort.sortArrayIndex(rs.getArrayFromResultSet(), Column.ref_index-1);
    	}
    	catch (Exception e) 
    	{
			return null;
		}
    }
   
    /**
     * This method writes objects and its properties to text file
     * @param mid Master id of parent object
     * @param recordset Property list of parent object
     */
    public String writeToFile(String mid,String [] recordset)
    {
    	int i = 0;    		  	
        flag = false;
        boolean isObject = false;
        
        try
		{
        	if(counter == 0)
    		{
    			String Temp = "Tag"+Input.SEPARATOR+get.getItem(mid)+"\n";    			
				rafNew.writeBytes(Temp);
				counter++;
    		}
	        
	    	while(i < recordset.length)
	    	{
	    		flag = false;
	    		String record_elements[] = recordset[i].split("\t");
	            
	            String midVal = record_elements[midIndex];
	            System.out.println("The midval is :"+midVal);
	            String pidVal = record_elements[pidIndex];
	            System.out.println("The pidval is :"+pidVal);
	            String pvVal  = record_elements[pvIndex];
	            System.out.println("The pvVal is :"+pvVal);
	            String vtVal  = record_elements[vtIndex];
	            System.out.println("The vtVal is :"+vtVal);
	            String refVal = record_elements[refIndex];
	            System.out.println("refVal :"+refVal);   		
	            
	    		StringBuffer sbrTemp = new StringBuffer();
	    		String property = get.getItem(pidVal);
	    		
	    		if(objects.contains(property.toLowerCase()) || !this.fileformat.equalsIgnoreCase(".html"))
	    			isObject = true;
	    		
	    		if(property.equalsIgnoreCase("type"))
	    		{
	    			Hashtable<Object, Object> condition = new Hashtable<Object, Object>();
	    			condition.put("mid",pvVal);
	    			condition.put("pid", Input.TYPE);
	    			RecordSearch rs = new RecordSearch();
	    			rs.setConditionMap(condition);
	    			
		    		ResultSet rs1 = rs.getResultSet(); 
	    			String typeOfType = null;
	    			
		    		while(rs1.next())
		    			typeOfType = get.getItem(rs1.getString("PV"));
		    			rs1.close();
		    		
		    		if(typeOfType != null && (typeOfType.equalsIgnoreCase("tag") || typeOfType.equalsIgnoreCase("attribute") || !this.fileformat.equalsIgnoreCase(".html")))
		    		{
			    		sbrTemp.append(property+Input.SEPARATOR);
			    		
		    			if(!pvVal.equalsIgnoreCase("0"))
		                {
		    				String temp = get.getItem(pvVal);
		    				System.out.println(temp);
		                    sbrTemp.append(temp+Input.SEPARATOR);
		                    if(!property.equalsIgnoreCase("type") && !property.equalsIgnoreCase("report"))
		                    	flag = true;
		                }
		                else
		                {
		                    sbrTemp.append(vtVal+Input.SEPARATOR);
		            	}
		    			
		                if(refVal.equals("no$") || Integer.parseInt(refVal) == 0)
		                {
		                	sbrTemp.append(refVal+"\n");
		                }
		                else
		                {
		                    sbrTemp.append(get.getItem(refVal)+"\n");
		                }
		    		}
		    		else
		    		{
		    			sbrTemp = new StringBuffer();
		    			i++;
		    			continue;
		    		}
	    		}
	    		else
	    		{
	    			sbrTemp.append(property+Input.SEPARATOR);
	    			
	    			if(!pvVal.equalsIgnoreCase("0"))
	                {
	    				String temp = get.getItem(pvVal);
	    				System.out.println(temp);
	    				temp = Replace.Replace(temp, "\n", Input.WEBREPLACER);	    				
	    				System.out.println(temp);
	                    sbrTemp.append(temp+Input.SEPARATOR);	                    
                    	flag = true;
	                }
	                else
	                {
	                	vtVal = Replace.Replace(vtVal, "\n", Input.WEBREPLACER);	
	                    sbrTemp.append(vtVal+Input.SEPARATOR);
	            	}
	    			
	                if(refVal.equals("no$") || Integer.parseInt(refVal) == 0)
	                {
	                	sbrTemp.append(refVal+"\n");
	                }
	                else
	                {
	                    sbrTemp.append(get.getItem(refVal)+"\n");	                    
	                }	    			
	    		}
                
	    		System.out.println("The line to write is "+sbrTemp.toString());    	
	    		
	    		incrementLevel();
	    		
	    		synchronized (this)
	    		{
	    			rafNew.writeBytes(level+sbrTemp.toString());
				}
	    		
    			decrementLevel();
    			
	    		if(flag && isObject)
	    		{
		    		String [] v = this.serachForChildProperty(pvVal);
		    		
		    		if(v != null)
		    		{
		    			incrementLevel();
		    			GenerateTextFile gen = new GenerateTextFile(rafNew,level,counter);
		    			gen.setDatabase();
		    			gen.setFileFormat(this.fileformat);
		    			
		    			gen.writeToFile(pvVal,v);
		    			//level = gen.getLevel();
		    			//counter = gen.getCounter();
		    			gen = null;
		    			decrementLevel();
		    		}
		    		
		    		flag = isObject = false;
	    		}
	    		
	    		i++;	    			    		
    		}
	    	
	   }
		catch (Exception e) 
		{
			e.printStackTrace();
		}    
		return level;
    }
    
    public int getCounter() {
		return counter;
	}
    
    public String getLevel() {
		return level;
	}
    
   /* public void writeToFile1(String mid,String [] recordset)
    {

	int i = 0;    		  	
    flag = false;
    
    try 
	{        	
    	if(counter == 0)
		{
			String Temp = "Tag"+Input.ch+get.getItem(mid)+"\n";    			
			rafNew.writeBytes(Temp);
			counter++;
		}
        
    	while(i < recordset.length)
    	{
    		flag = false;
    		String record_elements[] = recordset[i].split("\t");
            
            String midVal = record_elements[midIndex];
            System.out.println("The midval is :"+midVal);
            String pidVal = record_elements[pidIndex];
            System.out.println("The pidval is :"+pidVal);
            String pvVal  = record_elements[pvIndex];
            System.out.println("The pvVal is :"+pvVal);
            String vtVal  = record_elements[vtIndex];
            System.out.println("The vtVal is :"+vtVal);
            String refVal = record_elements[refIndex];
            System.out.println("refVal :"+refVal);   		
            
    		StringBuffer sbrTemp = new StringBuffer();
    		String property = get.getItem(pidVal);
    		
    		if(property.equalsIgnoreCase("type"))
    		{
    			Hashtable<Object, Object> condition = new Hashtable<Object, Object>();
    			condition.put("mid",pvVal);
    			condition.put("pid", Input.TYPE);
    			RecordSearch rs = new RecordSearch(db);
    			rs.setConditionMap(condition);
    			
	    		ResultSet rs1 = rs.getResultSet(); 
    			String typeOfType = null;
    			
	    		while(rs1.next())
	    			typeOfType = get.getItem(rs1.getString("PV"));
	    		
	    		if(typeOfType != null && (typeOfType.equalsIgnoreCase("tag") || typeOfType.equalsIgnoreCase("attribute")))
	    		{
		    		sbrTemp.append(property+Input.ch);
    			
	    			if(!pvVal.equalsIgnoreCase("0"))
	                {
	                    sbrTemp.append(get.getItem(pvVal)+Input.ch);
	                    if(!property.equalsIgnoreCase("type") && !property.equalsIgnoreCase("report"))
	                    	flag = true;
	                }
	                else
	                {
	                    sbrTemp.append(vtVal+Input.ch);
	            	}
	    			
	                if(refVal.equals("no$") || Integer.parseInt(refVal) == 0)
	                {
	                	sbrTemp.append(refVal+"\n");
	                }
	                else
	                {
	                    sbrTemp.append(get.getItem(refVal)+"\n");
	                }
	    		}
	    		else
	    		{
	    			sbrTemp = new StringBuffer();
	    			i++;
	    			continue;
	    		}
    		}
    		else
    		{
    			sbrTemp.append(property+Input.ch);
    			
    			if(!pvVal.equalsIgnoreCase("0"))
                {
                    sbrTemp.append(get.getItem(pvVal)+Input.ch);
                    if(!property.equalsIgnoreCase("type") && !property.equalsIgnoreCase("report"))
                    	flag = true;
                }
                else
                {
                    sbrTemp.append(vtVal+Input.ch);
            	}
    			
                if(refVal.equals("no$") || Integer.parseInt(refVal) == 0)
                {
                	sbrTemp.append(refVal+"\n");
                }
                else
                {
                    sbrTemp.append(get.getItem(refVal)+"\n");	                    
                }	    			
    		}
            
    		System.out.println("The line to write is "+sbrTemp.toString());    	
    		
    		synchronized (this) 
    		{
    			incrementLevel();
    			rafNew.writeBytes(level+sbrTemp.toString());	    
    			decrementLevel();
			}
		
    		if(flag == true)
    		{
	    		String [] v = this.serachForChildProperty(pvVal);
	    		
	    		if(v != null)
	    		{
	    			incrementLevel();
	    			writeToFile(pvVal,v);
	    			decrementLevel();
	    		}
    		}
    		i++;	    			    		
		}
    	
	}
	catch (Exception e) 
	{
		e.printStackTrace();
	}  
    }*/

       
    /**
     * This method increments level of object hierarchy
     * @return Incremented level 
     */
    public String incrementLevel()
    {
    	try
    	{
    		level = level +Input.SEPARATOR; 
    		return level;
    	}
    	catch (Exception e) 
    	{
			return "";
		}
    }
    
    /**
     * This method decrements level of object hierarchy
     * @return Decremented level 
     */
    public void decrementLevel()
    {
    	String temp = "";
    	System.out.println(level);
    	
    	if(level.length() == 0)
    	{
    		System.out.println(level+"     is zero");
		}
    	else
    	{
	    	for(int x = 0;x < level.length();x++)
	    	{
	    		if(level.charAt(x) == '\t' && x>0)
	    		{
	    			temp = temp + '\t';
	    		}
	    	}
    	}
    	
    	level = temp;
    }
}
